
#ifndef _MEMBER_BGRIDLAYOUT_H_
#define _MEMBER_BGRIDLAYOUT_H_

#include <BTable>
#include <BWidget>
#include <BGridLayout>
#include "ILayoutItem.h"

#define gridlayout_member(gridlayout)		((member_BGridLayout*)((BGridLayout*)gridlayout)->_ptr)

namespace BWE
{
	class GridHead
	{
	public:
		inline GridHead()
		{
			metaSize = 0;
			dragSize = 0;
			dirty = true;
			ignored = false;
			finished = true;
			baseSize = 0;
			fixedPolicy = Policy_None;
			fixedStretch = -1.0f;
			sizeStretch = fixedStretch;
			sizePolicy = fixedPolicy;
			hintSize = 0;
			minSize = 0;
			maxSize = 999999;
			fixedSize = 0;
			realSize = 0;
		}
		inline void prepare()
		{
			finished = false;
			realSize = 0;
			if (sizePolicy == Policy_None)
			{
				finished = true;
			}
			else if (sizePolicy == Policy_Fixed)
			{
				finished = true;
				realSize = fixedSize;
			}
			else if (sizePolicy == Policy_Preferred)
			{
				finished = true;
				realSize = hintSize;
			}
			if (sizePolicy & Policy_Fixed)
			{
				realSize = bMax(realSize, fixedSize);
			}
			if (sizePolicy & Policy_Preferred)
			{
				realSize = bMax(realSize, hintSize);
			}
			if (fixedStretch == 0)
			{
				finished = true;
			}
			realSize = bClamp(realSize, minSize, maxSize);
		}

		int			metaSize;
		int			dragSize;
		bool		dirty;
		bool		ignored;
		Policy		fixedPolicy;
		float		fixedStretch;
		int			baseSize;
		bool		finished;
		Policy		sizePolicy;
		float		sizeStretch;
		int			minSize;
		int			maxSize;
		int			realSize;
		int			hintSize;
		int			fixedSize;
		BRect		rect;
	};

	class member_BGridLayout
	{
	public:
		member_BGridLayout(BGridLayout* layout);
		~member_BGridLayout();

		void expandTable(int row, int column);
		void dirtyCell(int row, int column);

		BRect rowHandleRect(int index);
		BRect columnHandleRect(int index);
		void checkRowHandle(int& handle);
		void checkColumnHandle(int& handle);
		bool dragHandle(const BPoint& pos);

		void prepareCells();
		void distributeWidth();
		void distributeHeight();
		void applyRects();

	public:
		BGridLayout*		boss;
		int					rowSpacing;
		int					columnSpacing;
		BSize				handleSize;
		bool				splitable;

		bool				dirty;
		BSize				totalBaseSize;
		BSizeStretch		totalStretch;
		int					rowHandle;
		int					columnHandle;
		BRange				leftLimit;
		BRange				rightLimit;
		BRange				upLimit;
		BRange				downLimit;
		bool				pressed;
		BPoint				pressCenter;
		BArray<GridHead>	rowHeads;
		BArray<GridHead>	columnHeads;
		BTable<ILayoutItem>	items;
	};
}

#endif
